package wator.model;

import java.util.Map;

/**
 * A movement strategy can be used to update the direction of an agent. Thus,
 * the movement is decoupled from the actual agent implementation and
 * exchangeable. However, note that agents can implement their own
 * move() methods and the available strategies are more predefined suggestions.
 * 
 * @see AvailableMovementStrategies
 */
public interface MovementStrategy {
	
	/**
	 * Applies this movement strategy. This method defines the locomotion 
	 * behavior of the agent using this strategy. The updated direction vector 
	 * should be returned. The decision can be made on basis of the neighboring
	 * individuals of all types. Implementations are required to check if 
	 * there is already another individual in the cell to go.
	 * 
	 * @param agent the agent for which the direction should be calculated
	 * @param neighborhood the current neighborhood of this agent
	 * @return the updated direction vector
	 * @throws NullPointerException if one of the argument is null
	 */
	IntegerVector apply(Agent agent, Neighborhood neighborhood);
	
	/**
	 * Set a parameter value for this strategy. This method should only be called
	 * with keys given by {@link #getParameters()}.
	 * 
	 * @param key name of the parameter
	 * @param value of the parameter
	 * @see #getParameters()
	 */
	void setParameter(String key, int value);
	
	/**
	 * Get a map containing all parameters and their current values of this
	 * strategy instance.
	 * 
	 * @return a map with parameters
	 * @see #setParameter(String, int)
	 */
	Map<String, Integer> getParameters();
	
	/**
	 * Get the name of this strategy.
	 * 
	 * @return a string representation of the strategy
	 */
	String getName();
}
